﻿#region Usings

using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Web.Mvc;
using Omu.Awesome.Core;
using XPressify.Core;
using XPressify.Data.Helpers;
using XPressify.Helpers;
using XPressify.Models;
using XPressify.Data;
using NotificationType = XPressify.Models.NotificationType;

#endregion

namespace XPressify.Controllers
{
    public class PageController : SubjectController
    {
        //
        // GET: /Page/
        [Authorize]
        public ActionResult PageOwnerList(int? page)
        {
            var user = CurrentUser;

            var pages =
                Repository.AsQueryable<Relationship>().Where(
                    rel => rel.BaseSubject.Id == user.Id && rel.Status == RelationshipStatus.Confirmed).Select(
                        rel => rel.BaseSubject2).OfType<Page>();
            var pagePageable = pages.GetPageable(page ?? 1, 5, (g => g.Created));
            var pageList = new List<PageModel>();
            foreach (var @onePage in pagePageable.Page)
            {
                var admin =
                    Repository.AsQueryable<Relationship>().Where(
                        x =>
                        x.BaseSubjectId2 == @onePage.Id && x.RelationType == RelationshipType.AdministratorOf &&
                        x.Status == RelationshipStatus.Confirmed).Select
                        (x => x.BaseSubject).OfType<User>().SingleOrDefault();

                var isMember =
                    Repository.AsQueryable<Relationship>().Any(
                        rel =>
                        rel.BaseSubject.Id == user.Id && rel.BaseSubject2.Id == @onePage.Id &&
                        rel.RelationType == RelationshipType.MemberOf && rel.Status == RelationshipStatus.Confirmed);

                var model = new PageModel
                                {
                                    Administrator = admin,
                                    Page = @onePage,
                                    IsAdmin = admin == CurrentUser,
                                    SubjectId = user.Id,
                                    IsMemeber = isMember
                                };
                pageList.Add(model);
            }
            var pageModelPageable = new Pageable<PageModel> { Page = pageList, PageCount = pagePageable.PageCount, PageIndex = pagePageable.PageIndex };
            return View("PageList", pageModelPageable);
        }


        [Authorize]
        public ActionResult PageViewerList(Guid id, int? page)
        {
            var viewerUser = CurrentUser;
            var ownerUser = Repository.AsQueryable<User>().SingleOrDefault(us => us.Id == id);
            var pages =
                Repository.AsQueryable<Relationship>().Where(
                    rel => rel.BaseSubject.Id == ownerUser.Id && rel.Status == RelationshipStatus.Confirmed).Select(
                        rel => rel.BaseSubject2).OfType<Page>().Where(pg => pg.PrivacyType == SubjectPrivacy.Public);
//            var pagePageable = pages.GetPageable(page ?? 1, 5, (g => g.Created));
            var pageList = new List<PageModel>();
            foreach (var @onePage in pages)
            {
                var admin =
                    Repository.AsQueryable<Relationship>().Where(
                        x =>
                        x.BaseSubjectId2 == @onePage.Id && x.RelationType == RelationshipType.AdministratorOf &&
                        x.Status == RelationshipStatus.Confirmed).Select
                        (x => x.BaseSubject).OfType<User>().SingleOrDefault();

                var isMember =
                    Repository.AsQueryable<Relationship>().Any(
                        rel =>
                        rel.BaseSubject.Id == viewerUser.Id && rel.BaseSubject2.Id == @onePage.Id &&
                        rel.RelationType == RelationshipType.MemberOf && rel.Status == RelationshipStatus.Confirmed);

                var model = new PageModel
                                {
                                    Administrator = admin,
                                    Page = @onePage,
                                    IsAdmin = admin == viewerUser,
                                    SubjectId = ownerUser.Id,
                                    IsMemeber = isMember
                                };
                pageList.Add(model);
            }
//            var pageModelPageable = new Pageable<PageModel> { Page = pageList, PageCount = pagePageable.PageCount, PageIndex = pagePageable.PageIndex };
            return View("PageViewerList", pageList);
        }


        //
        // GET: /Page/Details/5
        [Authorize]
        public ActionResult PageDetails(Guid id, Guid? postId)
        {
            var page = Repository.AsQueryable<Page>().SingleOrDefault(pg => pg.Id == id);
            if (page == null)
            {
                // notify
                var notifyModel = new NotifyModel
                {
                    Title = "XPressify - Page",
                    Header = "Page",
                    Body = "Page does not exist",
                    NotificationType = NotificationType.Notification
                };
                return RedirectToAction("Notify", "Home", notifyModel);
            }
            var administrator = Repository.GetAdminOf(id);
            var user = CurrentUser;
            var administratorBlocked = // try to find if organizer is one of the blocked user, if so then we not show it
                Repository.AsQueryable<Relationship>().Any(
                    rel =>
                    ((rel.BaseSubject.Id == user.Id && rel.BaseSubject2.Id == administrator.Id) ||
                     (rel.BaseSubject2.Id == user.Id && rel.BaseSubject.Id == administrator.Id)) &&
                    rel.RelationType == RelationshipType.FriendOf && rel.Status == RelationshipStatus.Blocked);


            var isMemberOfPage =
                Repository.AsQueryable<Relationship>().Any(
                    rel =>
                    rel.BaseSubject.Id == user.Id && rel.BaseSubject2.Id == page.Id &&
                    rel.Status == RelationshipStatus.Confirmed &&
                    rel.RelationType == RelationshipType.MemberOf);

            var wallAlbum =
                Repository.AsQueryable<Album>().SingleOrDefault(al => al.BaseSubject.Id == page.Id && al.IsWall);

            //get wall album cover picture
            var coverPicture = wallAlbum.Medias.SingleOrDefault(ph => ph.IsCover);
            var path = "";
            var hasCoverPicture = true;
            if (coverPicture != null)
                path = "/Media/" + wallAlbum.BaseSubject.Id + "/" + wallAlbum.Id + "/" + coverPicture.Id + "." + coverPicture.FileType;
            else if (coverPicture == null && wallAlbum.IsProfile == false)
            {
                path = "/Media/Image/DefaultCover.jpg";
                hasCoverPicture = false;
            }

            //get all posts from owner user and put them in dictionary
            var dictionary = new Dictionary<Post, List<Post>>();

            var allPosts = new List<Post>();

            if(postId != null)
            {
                allPosts =
                Repository.AsQueryable<Post>().Where(
                    pst => pst.Id == postId && pst.PostType == PostType.Post).OrderByDescending(st => st.Created).ToList();
            }
            else
            {
                allPosts =
                Repository.AsQueryable<Post>().Where(
                    pst => pst.BaseSubject.Id == page.Id && pst.PostType == PostType.Post).OrderByDescending(st => st.Created).ToList();
            }

            
            foreach (var post in allPosts)
            {
                var allComments = Repository.GetAllComments(post);
                dictionary.Add(post, allComments);
            }

            var currentUserProfilePicturePath = Repository.GetProfilePicturePath(user.Id);


            var model = new PageModelDetails
                            {
                                Id = page.Id,
                                Name = page.Name,
                                Description = page.Description,
                                Username = page.Username,
                                IsAdministrator = administrator.Id == CurrentUser.Id,
                                Administrator = administrator,
                                AdministratorBlocked = administratorBlocked,
                                HasCoverPictureAlbum = hasCoverPicture,
                                IsMember = isMemberOfPage,
                                WallAlbumCoverPicturePath = path,
                                WallAlbumId = wallAlbum.Id,
                                CurrentUserProfilePicturePath = currentUserProfilePicturePath,
                                PagePrivacyType = page.PrivacyType,
                                AllPosts = dictionary,
                                CurrentUser = user,
                                MembersCanPost = page.MembersCanPost
                            };
            return View(model);
        }

        //
        // GET: /Page/Create
        [Authorize]
        public ActionResult PageCreate()
        {
            return View();
        }

        //
        // POST: /Page/Create
        [Authorize]
        [HttpPost]
        public ActionResult PageCreate(PageModelCreate model)
        {
            if(ModelState.IsValid)
            {
                try
                {
                    var page = new Page
                    {
                        Id = Guid.NewGuid(),
                        Name = model.Name,
                        Description = model.Description,
                        Username = "",
                        Created = DateTime.Now,
                        Type = SubjectType.Page,
                        PrivacyType = Convert.ToInt16(model.Privacy),
                        MembersCanPost = model.MembersCanPost
                    };
                    Repository.AddObject(page);

                    var relationship = new Relationship
                    {
                        Id = Guid.NewGuid(),
                        Type = ObjectType.Relationship,
                        Created = DateTime.Now,
                        Description = RelationshipType.AdministratorOfText,
                        BaseSubject = CurrentUser,
                        BaseSubject2 = page,
                        Status = RelationshipStatus.Confirmed,
                        RelationType = RelationshipType.AdministratorOf,
                        Name = RelationshipType.AdministratorOfText,
                        PrivacyType = ObjectPrivacy.FriendsOnly
                    };
                    Repository.AddObject(relationship);

                    var pageWallAlbum = new Album()
                    {
                        BaseSubject = page,
                        Created = DateTime.Now,
                        Id = Guid.NewGuid(),
                        IsProfile = false,
                        IsWall = true,
                        Name = "Wall album",
                        Description = "",
                        MediaType = AlbumMediaType.Mix,
                        Type = ObjectType.Album,
                        PrivacyType = ObjectPrivacy.Everyone,
                        Location = ""
                    };
                    Repository.AddObject(pageWallAlbum);

                    var newPostDummy = new Post
                    {
                        BaseObject = pageWallAlbum,
                        BaseSubject = pageWallAlbum.BaseSubject,
                        Content = "",
                        Id = Guid.NewGuid(),
                        Description = "Post dummy - wall album for page",
                        Title = "Post dummy - wall album for page",
                        Type = BaseMessageType.Post,
                        PostType = PostType.PostDummy,
                        Created = DateTime.Now,
                        CommentType = CommentType.PostWithItsComments
                    };
                    Repository.AddObject(newPostDummy);
                    Repository.SaveChanges();

                    //create physical folder
                    var path = Server.MapPath("~/Media/" + page.Id + "/"); // create a event directory
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path); // create directory
                    }
                    path = Server.MapPath("~/Media/" + page.Id + "/" + pageWallAlbum.Id + "/");
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path); // create directory
                    }
                    path = Server.MapPath("~/Media/" + page.Id + "/" + pageWallAlbum.Id + "/CoverPicture");
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path); // create directory
                    }

                    //create a default cover picture path
                    path = Server.MapPath("~/Media/Image/DefaultCover.jpg");
                    var newPath = Server.MapPath("~/Media/" + page.Id + "/" + pageWallAlbum.Id + "/CoverPicture/CoverPicture");
                    var coverInfo = new FileInfo(path);
                    coverInfo.CopyTo(newPath);

                    return Json(model);
                }
                catch
                {
                    return View(model);
                }
            }
            return View(model);
        }

        //
        // GET: /Page/Edit/5
        [Authorize]
        public ActionResult PageEdit(Guid id)
        {
            var page = Repository.AsQueryable<Page>().SingleOrDefault(pg => pg.Id == id);
            var admin = Repository.GetAdminOf(id);
            var user = CurrentUser;
            if (admin == null || admin.Id != user.Id)
            {
                return RedirectToAction("ProfileView", "Profile", new { id = user.Id });
            }
            var model = new PageModelEdit
                            {
                                Name = page.Name,
                                Description = page.Description,
                                PageId = page.Id,
                                MembersCanPost = page.MembersCanPost,
                                Privacy = page.PrivacyType.ToString()
                            };
            return View(model);
        }

        //
        // POST: /Page/Edit/5
        [Authorize]
        [HttpPost]
        public ActionResult PageEdit(Guid id, PageModelEdit model)
        {
            if(ModelState.IsValid)
            {
                try
                {
                    var page = Repository.AsQueryable<Page>().SingleOrDefault(pg => pg.Id == id);

                    //put all new values in dictionary key = what value = new value // only if they are different so value is changed
                    var changes = new Dictionary<string, string>();
                    if(page.Name != model.Name)
                        changes.Add("name", model.Name);
                    if(page.Description != model.Description)
                        changes.Add("description", model.Description);
                    var privacy = Convert.ToInt16(model.Privacy);
                    if (page.PrivacyType != privacy)
                    {
                        var newValueString = privacy == SubjectPrivacy.Public ? "public" : "private";
                        changes.Add("privacy", newValueString);
                    }
                    CreateNotification(page.Id, page.FullName, changes);

                    page.Name = model.Name;
                    page.Description = model.Description;
                    page.MembersCanPost = model.MembersCanPost;
                    page.PrivacyType = Convert.ToInt16(model.Privacy);
                    Repository.SaveChanges();
                    return Json(model);
                }
                catch
                {
                    return View(model);
                }
            }
            return View(model);
        }


        [Authorize]
        [HttpPost]
        public ActionResult PageDelete(PageModelDelete model)
        {
            try
            {
                var page = Repository.AsQueryable<Page>().SingleOrDefault(pg => pg.Id == model.Id);
                var admin = Repository.GetAdminOf(model.Id);
                var user = CurrentUser;
                if (admin == null || admin.Id != user.Id)
                {
                    return RedirectToAction("ProfileView", "Profile", new { id = user.Id });
                }
                var relationships =
                    Repository.AsQueryable<Relationship>().Where( // select all relationships that page have
                        x => x.BaseSubjectId == page.Id || x.BaseSubjectId2 == page.Id);
                foreach (var relationship in relationships)
                {
                    Repository.DeleteObject(relationship); // delete all relationships with page
                }

                var path = Server.MapPath("~/Media/" + page.Id + "/");
                if (Directory.Exists(path))
                {
                    Directory.Delete(path, true); // delete physical directory
                }
                Repository.SaveChanges();
                DeleteAllBaseObjects(page.Id);
                Repository.DeleteObject(page);
                Repository.SaveChanges();

                return RedirectToAction("PageOwnerList");
            }
            catch
            {
                return View(model);
            }
        }


        [Authorize]
        [HttpPost]
        public ActionResult PageRemove(PageModelDelete model)
        {
            try
            {
                var page = Repository.AsQueryable<Page>().SingleOrDefault(pg => pg.Id == model.Id);
                var user = CurrentUser;

                var relationship =
                    Repository.AsQueryable<Relationship>().SingleOrDefault(
                        rel =>
                        rel.BaseSubject.Id == user.Id && rel.BaseSubject2.Id == page.Id &&
                        rel.RelationType == RelationshipType.MemberOf);

                if(relationship != null)
                {
                    Repository.DeleteObject(relationship);
                    Repository.SaveChanges();
                }
                return RedirectToAction("PageOwnerList");
            }
            catch
            {
                return View();
            }
        }


        [Authorize]
        public ActionResult PageMembers(Guid id)
        {
            var user = CurrentUser;
            var blockedFriends =                            // all users that are blocked
                Repository.AsQueryable<Relationship>().Where(
                    rel =>
                    (rel.BaseSubject.Id == user.Id || rel.BaseSubject2.Id == user.Id) &&
                    rel.RelationType == RelationshipType.FriendOf && rel.Status == RelationshipStatus.Blocked);
            var members = Repository.GetMembersOf(id).Where(mem => !blockedFriends.Any(
                bl => (bl.BaseSubject.Id == mem.Id || bl.BaseSubject2.Id == mem.Id)));

            var listParticipants = new List<SuggestedFans>();
//            var participantPageable = members.GetPageable(page ?? 1, 50, (g => g.Created));
            foreach (var member in members)
            {
                var memberProfilePicturePath = Repository.GetProfilePicturePath(member.Id);
                var newParticipant = new SuggestedFans()
                {
                    FullName = member.FullName,
                    Id = member.Id,
                    ProfilePicturePath = memberProfilePicturePath,
                };
                listParticipants.Add(newParticipant);
            }
            var model = new PageMembersModel()
            {
                PageId = id,
                CurrentUserId = user.Id,
                Members = listParticipants.ToArray()
//                Page = listParticipants,
//                PageCount = participantPageable.PageCount,
//                PageIndex = participantPageable.PageIndex
            };
            return View(model);
        }

        [Authorize]
        public ActionResult InviteFriendsToPage(Guid id)
        {
            var user = CurrentUser;

            var allFriends = Repository.GetFriendsOf(user.Id);
            var friendsLookupList = new List<FriendsLookupModels>();
            foreach (var friend in allFriends)
            {
                var newMember = new FriendsLookupModels()
                {
                    FirstName = friend.FirstName,
                    Fullname = friend.FullName,
                    LastName = friend.LastName,
                    Id = friend.Id,
                    ProfilePicturePath = Repository.GetProfilePicturePath(friend.Id),
                    Selected = false
                };
                friendsLookupList.Add(newMember);
            }
            var json = JsonHelper.Serialize(friendsLookupList);
            Session["allFriends"] = json;


            var model = new InvitePageModel
                            {
                                PageId = id,
                                CurrentUserId = user.Id
                            };
            return View(model);
        }


        [Authorize]
        [HttpPost]
        public ActionResult InviteFriendsToPage(InvitePageModel model)
        {
            if (model.UsersSelected == null)
            {
                return View(model);
            }
            //users that already got requested
            var usersAlreadyRequsted =
                Repository.AsQueryable<Relationship>().Where(
                    rel => rel.BaseSubject2.Id == model.PageId && rel.RelationType == RelationshipType.MemberOf).
                    Select(rel => rel.BaseSubject).OfType<User>().Select(x => x.Id);
            //useres who were selected and not requested already
            var selectedUsers =
                Repository.AsQueryable<User>().Where(
                    u => model.UsersSelected.Contains(u.Id) && !usersAlreadyRequsted.Contains(u.Id));

            var page = Repository.AsQueryable<Page>().SingleOrDefault(pg => pg.Id == model.PageId);
            var currentUser = CurrentUser;
            foreach (var suggestedMemeberse in selectedUsers)
            {
                var relationship = new Relationship
                                        {
                                            Id = Guid.NewGuid(),
                                            PrivacyType = ObjectPrivacy.FriendsOnly,
                                            BaseSubject = suggestedMemeberse,
                                            BaseSubject2 = page,
                                            Created = DateTime.Now,
                                            RelationType = RelationshipType.MemberOf,
                                            Description = RelationshipType.MemberOfText,
                                            Status = RelationshipStatus.Requested,
                                            Type = ObjectType.Relationship,
                                            Name = RelationshipType.MemberOfText
                                        };
                Repository.AddObject(relationship);
                SendEmailConfirmPageInvitation(relationship);

                //InvitesYour notification
                var newNotification = new Notification()
                {
                    Active = true,
                    BaseSubject = suggestedMemeberse,
                    Created = DateTime.Now,
                    Id = Guid.NewGuid(),
                    Type = BaseMessageType.Notification
                };
                var viewData3 = new
                {
                    BaseSubjectType = "page",
                    SubjectId = model.PageId,
                    SubjectFullname = page.FullName,
                    InviterId = currentUser.Id,
                    InviterFullname = currentUser.FullName
                };

                var viewDictionary3 = viewData3.ToViewDataDictionary();
                newNotification.Content = ControlToString("~/Views/Notification/InvitesYou.cshtml", viewDictionary3);
                Repository.AddObject(newNotification);
            }
            Repository.SaveChanges();

            return Json(model);
        }


        [Authorize]
        public ActionResult ChangeAdmin(Guid id)
        {
            var memebers = Repository.GetMembersOf(id);
            var friendsLookupList = new List<FriendsLookupModels>();
            foreach (var memeber in memebers)
            {
                var newMember = new FriendsLookupModels()
                                    {
                                        FirstName = memeber.FirstName,
                                        Fullname = memeber.FullName,
                                        LastName = memeber.LastName,
                                        Id = memeber.Id,
                                        ProfilePicturePath = Repository.GetProfilePicturePath(memeber.Id),
                                        Selected = false
                                    };
                friendsLookupList.Add(newMember);
            }
            var json = JsonHelper.Serialize(friendsLookupList);
            Session["allMembers"] = json;

            var model = new ChangeAdminModel
            {
                EventId = id, 
                SubjectId = id,
                CurrentUserId = CurrentUser.Id
            };

            return View(model);
        }


        [Authorize]
        [HttpPost]
        public ActionResult ChangeAdmin(Guid id, ChangeAdminModel model)
        {
            var page = Repository.AsQueryable<Page>().Single(pg => pg.Id == id);
            var selectedMember = Repository.AsQueryable<User>().SingleOrDefault(usr => usr.Id == model.SelectedId);

            if(selectedMember != null)
            {
                //this is a temporary relationship till user doesnt accept it we will change his previous relationship to admin and we will delete this one
                var relationship = new Relationship
                {
                    Id = Guid.NewGuid(),
                    PrivacyType = ObjectPrivacy.FriendsOnly,
                    BaseSubject = selectedMember,
                    BaseSubject2 = page,
                    Created = DateTime.Now,
                    RelationType = RelationshipType.AdministratorOf,
                    Description = RelationshipType.AdministratorOfText,
                    Status = RelationshipStatus.Requested,
                    Type = ObjectType.Relationship,
                    Name = RelationshipType.AdministratorOfText
                };
                Repository.AddObject(relationship);
                Repository.SaveChanges();

                SendEmailConfirmAdminInvitation(relationship);

                return Json(model);
            }
            return View(model);

        }


        public ActionResult BecomeMember(Guid id)
        {
            var page = Repository.AsQueryable<Page>().Single(ev => ev.Id == id);
            var currentUser = CurrentUser;

            //try to look any relationship with currentUser and event e of type MemberOf independing of relationship status
            var previousRelationship =
                Repository.AsQueryable<Relationship>().SingleOrDefault(
                    rel =>
                    rel.BaseSubject.Id == currentUser.Id && rel.BaseSubject2.Id == page.Id &&
                    rel.RelationType == RelationshipType.MemberOf);
            if (previousRelationship != null)
            {
                previousRelationship.Status = RelationshipStatus.Confirmed;
                Repository.SaveChanges();
                CreatePagePost(previousRelationship, page); // create a post
            }
            // we create a new relationship with current user and event of type MemberOf and status confirmed
            else
            {
                var newRelationship = new Relationship()
                {
                    BaseSubject = currentUser,
                    BaseSubject2 = page,
                    Created = DateTime.Now,
                    Id = Guid.NewGuid(),
                    Name = RelationshipType.MemberOfText,
                    Description = RelationshipType.MemberOfText,
                    PrivacyType = ObjectPrivacy.FriendsOnly,
                    RelationType = RelationshipType.MemberOf,
                    Status = RelationshipStatus.Confirmed,
                    Type = ObjectType.Relationship
                };
                Repository.AddObject(newRelationship);
                Repository.SaveChanges();
                CreatePagePost(newRelationship, page); // create a post
            }
            return RedirectToAction("PageDetails", "Page", new { id = page.Id });
        }


        #region Subject Members
        public override ActionResult ConfirmRelationshipNotification(Relationship relationship)
        {
            var model = new NotifyModel
                            {
                                Title = "Invite request",
                                Header = "Confirm page invite",
                                Body = "Page invite successfully confirmed.",
                                NotificationType = NotificationType.Notification
                            };

            return RedirectToAction("Notify", "Home", model);
        }

        public override ActionResult PostponeRelationshipNotification(Relationship relationship)
        {
            var model = new NotifyModel
                            {
                                Title = "Invite request",
                                Header = "Postpone page invite",
                                Body = "Page invite successfully postponed.",
                                NotificationType = NotificationType.Notification
                            };

            return RedirectToAction("Notify", "Home", model);
        }

        public override ActionResult PostponeFailedRelationshipNotification(Relationship relationship)
        {
            var model = new NotifyModel
                            {
                                Title = "Invite request",
                                Header = "Postpone page invite",
                                Body =
                                    "Invitation to page request couldn't be postponed, because the invitation was already confrirmed.",
                                NotificationType = NotificationType.Notification
                            };

            return RedirectToAction("Notify", "Home", model);
        }

        #endregion

        #region Email sending


        public bool SendEmailConfirmAdminInvitation(Relationship rel)
        {
            var user = CurrentUser;
            var viewData = new
            {
                XSettings.SiteName,
                FriendName = rel.BaseSubject.FullName,
                YourName = user.FullName,
                EventName = ((Page)rel.BaseSubject2).Name,
                RelationshipId = rel.Id,
                ConfirmFriendshipUrl =
                    new Uri(HttpContext.Request.Url,
                            Url.Action("ConfirmAdminRelationship", "Page", new { id = rel.Id })).ToString(),
                PostponeFriendshipUrl =
                    new Uri(HttpContext.Request.Url,
                            Url.Action("PostponeRelationship", "Page", new { id = rel.Id })).ToString(),
                XSettings.SiteUrl,
                YourProfileUrl =
                    new Uri(HttpContext.Request.Url,
                            Url.Action("ProfileView", "Profile", new { id = user.Id })).ToString(),
                EventDetailsUrl =
                   new Uri(HttpContext.Request.Url,
                           Url.Action("PageDetails", "Page", new { id = rel.BaseSubject2.Id })).ToString()
            };
            var viewDictionary = viewData.ToViewDataDictionary();

            return SendTemplatedEmail(new List<string> { ((User)rel.BaseSubject).Email }, String.Format("{0} site: Administrator confirmation is required", XSettings.SiteName),
                                                   "~/Views/Email/ConfirmAdminInvitation.cshtml", viewDictionary);
        }


        public bool SendEmailConfirmPageInvitation(Relationship rel)
        {
            var user = CurrentUser;
            var viewData = new
                               {
                                   XSettings.SiteName,
                                   FriendName = rel.BaseSubject.FullName,
                                   YourName = user.FullName,
                                   PageName = rel.BaseSubject2.FullName,
                                   RelationshipId = rel.Id,
                                   ConfirmFriendshipUrl =
                                       new Uri(HttpContext.Request.Url,
                                               Url.Action("ConfirmRelationship", "Page", new {id = rel.Id})).ToString(),
                                   PostponeFriendshipUrl =
                                       new Uri(HttpContext.Request.Url,
                                               Url.Action("PostponeRelationship", "Page", new {id = rel.Id})).ToString(),
                                   XSettings.SiteUrl,
                                   YourProfileUrl =
                                       new Uri(HttpContext.Request.Url,
                                               Url.Action("ProfileView", "Profile", new { id = user.Id })).ToString(),
                                   PageDetailsUrl =
                                      new Uri(HttpContext.Request.Url,
                                              Url.Action("PageDetails", "Page", new { id = rel.BaseSubject2.Id })).ToString()
                               };
            var viewDictionary = viewData.ToViewDataDictionary();

            return SendTemplatedEmail(new List<string> {((User) rel.BaseSubject).Email},
                                                   String.Format("{0} site: Membership confirmation is required", XSettings.SiteName),
                                                   "~/Views/Email/ConfirmPageInvitation.cshtml", viewDictionary);
        }

        #endregion

        #region Extra Functions


        public void DeleteAllBaseObjects(Guid groupId)
        {
            //find all posts from event
            var allPosts = Repository.AsQueryable<Post>().Where(ps => ps.BaseSubject.Id == groupId);

            // if (Event->Post->BaseObject->SomeUser) and if (Event.delete->Post.delete !-> BaseObject->SomeUser)
            //BaseObject will be not deleted and it will not have post so we must delete it manually all BaseObjects connected with Event->Posts


            var allStatuses = Repository.AsQueryable<Status>().Where(st => allPosts.Any(pst => pst.BaseObject.Id == st.Id)).ToArray();
            foreach (var status in allStatuses)
            {
                Repository.DeleteObject(status);
            }
            var allNotes = Repository.AsQueryable<Note>().Where(no => allPosts.Any(pst => pst.BaseObject.Id == no.Id)).ToArray();
            foreach (var note in allNotes)
            {
                Repository.DeleteObject(note);
            }
            var allLinks = Repository.AsQueryable<Link>().Where(no => allPosts.Any(pst => pst.BaseObject.Id == no.Id)).ToArray();
            foreach (var link in allLinks)
            {
                Repository.DeleteObject(link);
            }
            var album = Repository.AsQueryable<Album>().SingleOrDefault(al => al.BaseSubject.Id == groupId);
            var medias = album.Medias.ToArray();
            foreach (var media in medias)
            {
                Repository.DeleteObject(media);
            }
            Repository.DeleteObject(album);
            Repository.SaveChanges();
        }

        public void CreateNotification(Guid pageId,string pageFullname, Dictionary<string,string> values)
        {
            //create a notifications
            var members = Repository.GetMembersOf(pageId).ToList();
            var admin = Repository.GetAdminOf(pageId);
            members.Add(admin);
            foreach (var member in members)
            {
                foreach (var value in values)
                {
                    //GroupEventPageChange notification
                    var newNotification = new Notification()
                    {
                        Active = true,
                        BaseSubject = member,
                        Created = DateTime.Now,
                        Id = Guid.NewGuid(),
                        Type = BaseMessageType.Notification
                    };
                    var viewData3 = new
                    {
                        BaseSubjectType = "page",
                        SubjectId = pageId,
                        SubjectFullname = pageFullname,
                        Value = value.Key,
                        Value2 = value.Value
                    };

                    var viewDictionary3 = viewData3.ToViewDataDictionary();
                    newNotification.Content = ControlToString("~/Views/Notification/GroupEventPageChange.cshtml", viewDictionary3);
                    Repository.AddObject(newNotification);
                }
                
            }
            Repository.SaveChanges();
        }

        #endregion
    }
}